package com.igoal.web;

import java.util.List;

import org.springframework.security.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.ui.ModelMap;
import org.springframework.util.Assert;

import com.igoal.dto.FriendDTO;
import com.igoal.dto.FriendRequestDTO;
import com.igoal.dto.GoalDTO;
import com.igoal.dto.MessageDTO;
import com.igoal.dto.PotentialFriendDTO;
import com.igoal.dto.ProfileCompleteDTO;
import com.igoal.dto.UserActivityLogDTO;
import com.igoal.dto.UserDTO;
import com.igoal.dto.UserStatusDTO;
import com.igoal.service.ActionLoggerService;
import com.igoal.service.GoalManager;
import com.igoal.service.MessageManager;
import com.igoal.service.UserManagerExt;
import com.igoal.utils.StringUtils;
import com.igoal.web.model.BaseModel;
import com.igoal.web.model.DummySettings;
import com.igoal.web.model.UpdateCompletenessModel;
import com.igoal.web.model.UserNotificatorModel;
import com.igoal.web.model.UserStatusModel;

@Service("controllerDelegate")
public class BaseControllerDelegate {
	public static final String AJAX_VIEW_PREFIX = "ajax/";
	public static final String DEFAULT_VIEW_PREFIX = "views/";
	public static final String ADMIN_VIEW_PREFIX = "admin/";
	
	public BaseControllerDelegate() {
	};

	public String getUserInSession() {
		return SecurityContextHolder.getContext().getAuthentication().getName();
	}

	public UserDTO getUserSession(UserManagerExt userManagerExt) {
		if (userManagerExt == null)
			return null;

		Assert.notNull(userManagerExt, "UserManagerExt is not initialized.");
		String userInSession = getUserInSession();
		Assert.notNull(userInSession, "User session error!");
		UserDTO user = userManagerExt.getUserByUsername(userInSession);
		Assert.notNull(user, "Data failure.");

		return user;
	}

	public boolean isLoginUser() {
		String userInSession = getUserInSession();
		return !userInSession.equalsIgnoreCase("roleAnonymous");
	}
	
	public void initUserStatus(UserManagerExt userManagerExt, UserDTO user, BaseModel model){
		if(userManagerExt == null || user == null || model == null)
			return;
		
		UserStatusModel userStatusModel = new UserStatusModel();
		UserStatusDTO userStatus = userManagerExt.getUserStatus(user);
		if (userStatus != null) {
			userStatusModel.setStatusText(userStatus.getUserStatus());
			userStatusModel.setStatusURL(userStatus.getImgURL());
			userStatusModel.setUpdatedSince(userStatus.getUpdateDate());
			userStatusModel.setUserStatusId(userStatus.getId());
			int countThumbedUpStatus = userManagerExt.countUserStatusThumbedUp(userStatus.getId());
			int countThumbedDownStatus = userManagerExt.countUserStatusThumbedDown(userStatus.getId());
			userStatusModel.setCountThumbedUpStatus(countThumbedUpStatus);
			userStatusModel.setCountThumbedDownStatus(countThumbedDownStatus);
		}
		
		model.setUserStatus(userStatusModel);
	}

	/**
	 * The notification information creator
	 * 
	 * @param user
	 *            user in session
	 * @param model
	 *            the controller model that extends from {@link BaseModel}
	 */
	public void initUserNotification(UserManagerExt userManagerExt,
			MessageManager messageManager, ActionLoggerService actionLoggerService, 
			UserDTO user, BaseModel model) {
		if (userManagerExt == null || messageManager == null || user == null || model == null) {
			return;
		}

		UserNotificatorModel notificatorModel = model.getNotificator();
		if(notificatorModel == null){
			notificatorModel = new UserNotificatorModel();
		}

		List<MessageDTO> newMessages = messageManager.getNewMessage(user.getId());
		notificatorModel.setMessages(newMessages);
		notificatorModel.setMessageCount(newMessages.size());

		List<FriendRequestDTO> friendRequests = userManagerExt.getFriendRequests(user.getUsername());
		notificatorModel.setFriendRequests(friendRequests);
		notificatorModel.setFriendRequestCount(friendRequests.size());
		
//		List<UserNotificationLogDTO> notifications = actionLoggerService.getNewNotificationsLog(user.getUsername(), null, false);
		notificatorModel.setNotificationCount(actionLoggerService.countNewNotificationLog(user.getUsername(), null, false));
		//notificatorModel.setNotifications(notifications);

		model.setNotificator(notificatorModel);		
	}
	
	public void initUserActivities(ActionLoggerService actionLoggerService, 
			UserDTO user, BaseModel model){
		if(actionLoggerService == null || user == null || model == null)
			return;
//		boolean isLoginUser = isLoginUser();
		
		List<UserActivityLogDTO> activities = actionLoggerService.getNewActivitiesLog(user.getUsername(), false, null, false);
		model.setActivities(activities);
	}
	
	public void initUserAvatar(UserManagerExt userManagerExt, UserDTO user, BaseModel model){
		if (userManagerExt == null || user == null || model == null) {
			return;
		}
		
		UserNotificatorModel notificatorModel = model.getNotificator();
		if(notificatorModel == null){
			notificatorModel = new UserNotificatorModel();
		}
		
		if (user.getAvatar() != null && StringUtils.isNotBlank(user.getAvatar())) {
			notificatorModel.setAvatarURL(user.getAvatar());
		} else {
			notificatorModel.setAvatarURL(DummySettings.DEFAULT_AVATAR_URL);
		}
		
		model.setNotificator(notificatorModel);
	}
	
	/**
	 * The user profile notification creator
	 * 
	 * @param user
	 *            user in session
	 * @param model
	 *            the controller model that extends from {@link BaseModel}
	 */
	public void initUserProfileNotification(UserManagerExt userManagerExt, UserDTO user,
			BaseModel model) {
		if (user == null || model == null) {
			return;
		}

		// completeness
		UpdateCompletenessModel updateCompleteness = new UpdateCompletenessModel();
		ProfileCompleteDTO completeDTO = userManagerExt.getProfileComplete(user);
		updateCompleteness.setUpdatedBasicInfo(completeDTO.getBasicInfo());
		updateCompleteness.setUpdatedAvatar(completeDTO.getAvatar());
		updateCompleteness.setUpdatedHobby(completeDTO.getHobby());
		updateCompleteness.setUpdatedGoal(completeDTO.getAddGoal());

		model.setUpdateCompleteness(updateCompleteness);
		model.setUserBiography(user.getAboutMe());
	}

	public void initPeopleYouMayKnow(UserManagerExt userManagerExt,
			UserDTO user, BaseModel model) {
		if (userManagerExt == null || user == null || model == null) {
			return;
		}

		// Map<String, List<FriendDTO>> pymk =
		// userManagerExt.getPeopleYouMayKnow(user);
		// if (pymk != null) {
		// Set<String> keys = pymk.keySet();
		// Assert.notEmpty(keys);
		// String[] usernames = keys.toArray(new String[1]);
		// String username = usernames[0];
		// List<FriendDTO> mutualFriends = pymk.get(username);
		// model.setPotentialFriend(username);
		// model.setPotentialFriendOnlineStatus(LoginStatus.isOnline(username));
		// model.setMutualFriends(mutualFriends);
		// } else {
		// model.setPotentialFriend(null);
		// model.setMutualFriends(null);
		// }
		List<PotentialFriendDTO> potentialFriends = userManagerExt.getPeopleYouMayKnow(user, true);
		if (potentialFriends != null && potentialFriends.size() > 0) {
			model.setPotentialFriends(potentialFriends);
		} else {
			model.setPotentialFriends(null);
		}
	}

	public void initMutualFriends(UserManagerExt userManagerExt, UserDTO owner,
			UserDTO publicUser, BaseModel model) {
		if (userManagerExt == null || owner == null || publicUser == null
				|| model == null) {
			return;
		}

		List<FriendDTO> mutualFriends = userManagerExt.getMutualFriends(owner, publicUser);
		if (mutualFriends != null && mutualFriends.size() > 0) {
			model.setMutualFriends(mutualFriends);
		} else {
			model.setMutualFriends(null);
		}
	}

	/**
	 * Get all friends
	 * 
	 * @param user
	 *            user in session
	 * @param model
	 *            the controller model that extends from {@link BaseModel}
	 */
	public void countFriends(UserManagerExt userManagerExt, UserDTO user, BaseModel model) {
		if (userManagerExt == null || user == null || model == null) {
			return;
		}
		model.setFriendCount(userManagerExt.countFriends(user.getUsername()));
	}

	/**
	 * Get random friends
	 * 
	 * @param userManagerExt
	 * @param user
	 * @param model
	 */
	public void initRandomFriendList(UserManagerExt userManagerExt, UserDTO user, BaseModel model) {
		if (userManagerExt == null || user == null || model == null) {
			return;
		}

		List<FriendDTO> allFriends = userManagerExt.getRandomFriends(user);
		model.setFriends(allFriends);
	}

	public void initSessionInformation(BaseModel model, UserManagerExt userManagerExt) {
		if (isLoginUser()) {
			model.setUserInSession(getUserInSession());
			UserDTO user = getUserSession(userManagerExt);
			model.setUserId(user.getId());
			
			String avatar = user.getAvatar();
			if (StringUtils.isBlank(avatar)) {
				avatar = DummySettings.DEFAULT_AVATAR_URL;
			}
			model.setUserAvatar(avatar);
			
			model.setUserAlias(StringUtils.buildDisplayName(user.getUsername(), user.getFirstName(), user.getMiddleName(), user.getLastName()));
		}
	}
	
	public void initMustDoGoal(BaseModel model, GoalManager goalManager){
		if(model == null || goalManager == null){
			return ;
		}
		
		if(isLoginUser()){
			String username = getUserInSession();
			GoalDTO mustDoGoal = goalManager.getMustDoGoal(username);
			if(mustDoGoal != null){
				model.setMustDoGoal(mustDoGoal);
			}
		}	
	}

	public void applyModel(ModelMap modelMap, BaseModel model) {
		modelMap.addAttribute("data", model);
	}
	
	public void applyModel(ModelMap modelMap, Object model) {
		modelMap.addAttribute("data", model);
	}
}
